using System;

namespace PropertyExpression.Common
{
    public static class Func
    {
        public static Func<TResult> New<TResult>(Func<TResult> func)
        {
            return func;
        }

        public static Func<T1, TResult> New<T1, TResult>(Func<T1, TResult> func)
        {
            return func;
        }

        public static Func<T1, T2, TResult> New<T1, T2, TResult>(Func<T1, T2, TResult> func)
        {
            return func;
        }

        public static Func<T1, T2, T3, TResult> New<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func)
        {
            return func;
        }

        public static Func<T1, T2, T3, T4, TResult> New<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func)
        {
            return func;
        }

        public static TResult Apply<T1, TResult>(Func<T1, TResult> func, T1 arg)
        {
            return func(arg);
        }

        public static Func<TResult> Lazy<TResult>(Func<TResult> func)
        {
            var valueIsSet = false;
            var value = default (TResult);
            return () => {
                if (!valueIsSet)
                {
                    value = func();
                    valueIsSet = true;
                }
                return value;
            };
        }
    }
}